package com.citywithincity.utils;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import javassist.CtClass;

/**
 * 数据类型转换
 * @author Randy
 *
 */
public class DataUtil {
	
	/**
	 * 各种语言的中间类型
	 */
	public static final String STRING = "String";
	
	public static final String LONG = "long";
	public static final String INT = "int";
	public static final String SHORT = "short";
	public static final String BYTE = "byte";
	public static final String CHAR = "char";
	
	public static final String BOOLEAN = "bool";
	
	public static final String DOUBLE = "double";
	public static final String FLOAT = "float";
	
	public static final String DATE = "date";
	public static final String BINARY = "binary";
	
	 
	
	
	/**
	 * 是否是基本类型
	 * @param map
	 * @param key
	 * @return
	 */
	private static Set<String> types;
	private static Map<String,Class<?>> simpleType;
	//各个语言通用的标准类型
	private static Map<String, String> standTypes;
	static{
		simpleType = new HashMap<String,Class<?>>();
		types = new HashSet<String>();
		standTypes = new HashMap<String, String>();
		types.add("java.lang.String");
		standTypes.put("java.lang.String", STRING);
		types.add("java.lang.Integer");
		standTypes.put("java.lang.Integer", INT);
		types.add("java.lang.Long");
		standTypes.put("java.lang.Long", LONG);
		
		types.add("java.lang.Float");
		standTypes.put("java.lang.Float", FLOAT);
		
		types.add("java.lang.Double");
		standTypes.put("java.lang.Double", DOUBLE);
		
		types.add("java.lang.Boolean");
		standTypes.put("java.lang.Boolean", BOOLEAN);
		
		types.add("java.lang.Short");
		standTypes.put("java.lang.Short", SHORT);
		
		types.add("java.lang.Byte");
		standTypes.put("java.lang.Byte", BYTE);
		
		types.add("java.lang.Char");
		standTypes.put("java.lang.Char", CHAR);
		//////////////////////////////////////////////////
		types.add("int");
		standTypes.put("int", INT);
		simpleType.put("int", int.class);
		
		types.add("double");
		standTypes.put("double", DOUBLE);
		simpleType.put("double", double.class);
		
		types.add("long");
		standTypes.put("long", LONG);
		simpleType.put("long", long.class);
		
		types.add("float");
		standTypes.put("float", FLOAT);
		simpleType.put("float", float.class);
		
		types.add("boolean");
		standTypes.put("boolean", BOOLEAN);
		simpleType.put("boolean", boolean.class);
		
		types.add("short");
		standTypes.put("short", SHORT);
		simpleType.put("short", short.class);
		
		types.add("char");
		standTypes.put("char", CHAR);
		simpleType.put("char", char.class);
		
		types.add("byte");
		standTypes.put("byte", BYTE);
		simpleType.put("byte", byte.class);
		
		
		types.add("java.util.Date");
		standTypes.put("java.util.Date", DATE);
		
		types.add("byte[]");
		standTypes.put("byte[]", BINARY);
		
	}
	
	/**
	 * 是否是简单数据类型
	 * 包括String
	 * @return
	 */
	public static boolean isSimple(Class<?> type){
		return simpleType.containsKey(type.getName());
	}
	
	/**
	 * 根据类名称判断是否是简单类型
	 * @param name
	 * @return
	 */
	public static boolean isSimple(String name){
		return simpleType.containsKey(name);
	}
	
	/**
	 * 是否是字段类型
	 * @param type
	 * @return
	 */
	public static boolean isColumnType(CtClass type){
		return types.contains(type.getName());
	}
	
	
	/**
	 * 
	 * @param map
	 * @param key
	 * @return
	 */
	public static int getInt(Map<String, ?> map,String key){
		return getInt(map, key, 0);
	}
	public static long getLong(Map<String, ?> map,String key){
		return getLong(map, key, 0);
	}
	public static long getLong(Map<String, ?> map,String key,long defaultValue){
		Object value = map.get(key);
		if(value==null)return defaultValue;
		if(value instanceof Long)return (Long)value;
		if(value instanceof Integer)return (Integer)value;
		if(value instanceof BigDecimal)return ((BigDecimal)value).longValue();
		if(value instanceof String){
			String str = (String)value;
			if(str.length()==0)return 0;
			return Integer.parseInt(str);
		}
		throw new ClassCastException("Type "+value.getClass()+" can not cast to long.");
	}
	public static int getInt(Map<String, ?> map,String key,int defaultValue){
		Object value = map.get(key);
		if(value==null)return defaultValue;
		if(value instanceof Integer)return (Integer)value;
		if(value instanceof BigDecimal)return ((BigDecimal)value).intValue();
		if(value instanceof String){
			String str = (String)value;
			if(str.length()==0)return 0;
			return Integer.parseInt(str);
		}
		if(value instanceof Long)return (int)(long)(Long)value;
		throw new ClassCastException("Type "+value.getClass()+" can not cast to int.");
	}
	
	public static String getString(Map<String, ?> map,String key){
		return getString(map, key, "");
	}
	public static double getDouble(Map<String, ?> map,String key){
		Object value = map.get(key);
		if(value instanceof Double){
			return (Double)value;
		}
		if(value instanceof BigDecimal){
			return ((BigDecimal)value).doubleValue();
		}
		if(value instanceof Integer){
			return (Integer)value;
		}
		if(value instanceof Float){
			return (Float)value;
		}
		if(value instanceof Long){
			return (Long)value;
		}
		if(value instanceof String){
			return Double.parseDouble((String)value);
		}
		return 0;
	}
	
	public static String getString(Map<String, ?> map,String key,String defaultValue){
		Object value = map.get(key);
		if(value==null)return defaultValue;
		return String.valueOf(value);
	}

	public static long toLong(Object value) {
		if(value==null)return 0;
		if(value instanceof Long)return (Long)value;
		if(value instanceof Integer)return (Integer)value;
		if(value instanceof BigDecimal)return ((BigDecimal)value).longValue();
		if(value instanceof String)return Long.parseLong((String)value);
		throw new RuntimeException("Type "+value.getClass()+" can not cast to long.");
	}

	public static int toInt(Object value) {
		if(value==null)return 0;
		if(value instanceof Integer)return (Integer)value;
		if(value instanceof Long)return (int)(long)(Long)value;
		if(value instanceof BigDecimal)return ((BigDecimal)value).intValue();
		if(value instanceof String)return Integer.parseInt((String)value);
		throw new RuntimeException("Type "+value.getClass()+" can not cast to long.");
	}
	
	/**
	 * 转成标准类型
	 * @param name
	 * @return
	 */
	public static Object toStandard(String name) {
		return standTypes.get(name);
	}

	public static Class<?> getSimpleType(String name) {
		
		return simpleType.get(name);
	}

	public static int getInt(HttpServletRequest request, String name) {
		String param = request.getParameter(name);
		if(param==null)return 0;
		return Integer.parseInt(param);
	}
	
	public static double getDouble(HttpServletRequest request, String name) {
		String param = request.getParameter(name);
		if(param==null)return 0;
		return Double.parseDouble(param);
	}

	public static double toDouble(Object value) {
		if(value == null)return 0;
		if(value instanceof Double)return (Double)value;
		if(value instanceof String) return Double.parseDouble((String)value);
		if(value instanceof Integer) return (Integer)value;
		if(value instanceof Float) return (Float)value;
		if(value instanceof Long) return (Long)value;
		return 0;
	}
	
	/**
	 * 将制定的转成
	 * @param value
	 * @param type
	 */
	public static Object convert(Object value, Class<?> type) {
		if(value == null){
			
			if(type.isPrimitive()){
				if(type == int.class){
					return 0;
				}else if(type == double.class){
					return 0;
				}else if(type == boolean.class){
					return false;
				}
			}
			return null;
		}
		Class<?> targetClass = value.getClass();
		if(targetClass == type){
			return value;
		}
		
		String stringValue = String.valueOf(value);
		
		if(type == int.class || type == Integer.class){
			return Integer.parseInt(stringValue);
		}
		
		if(type == boolean.class || type == Boolean.class){
			if(stringValue.equals("0")){
				return false;
			}
			if(stringValue.equals("1")){
				return true;
			}
			return Boolean.parseBoolean(stringValue);
		}
		
		
		if(type == long.class || type == Long.class){
			return Long.parseLong(stringValue);
		}
		
		return stringValue;
		
	}

	
	public static boolean toBoolean(Object value){
		
		if(value == null) return false;
		
		if(value instanceof Boolean){
			return (Boolean)value;
		}
		
		if(value instanceof BigDecimal){
			return ((BigDecimal)value).intValue() > 0;
		}
		
		if(value instanceof Integer){
			return (Integer)value > 0;
		}
		if(value instanceof Long){
			return (Long)value > 0;
		}
		
		return Boolean.parseBoolean(String.valueOf(value));
	}
	
	public static boolean getBoolean(Map<String, Object> extra, String key) {
		if(extra == null)return false;
		Object value = extra.get(key);
		return toBoolean(value);
	}
}
